/*      */ package com.zimbra.cs.service.formatter;
/*      */ 
/*      */ import com.google.common.annotations.VisibleForTesting;
/*      */ import com.google.common.base.Strings;
/*      */ import com.google.common.collect.Sets;
/*      */ import com.google.common.io.Closeables;
/*      */ import com.zimbra.common.calendar.ZCalendar.ZCalendarBuilder;
/*      */ import com.zimbra.common.calendar.ZCalendar.ZICalendarParseHandler;
/*      */ import com.zimbra.common.calendar.ZCalendar.ZVCalendar;
/*      */ import com.zimbra.common.localconfig.KnownKey;
/*      */ import com.zimbra.common.localconfig.LC;
/*      */ import com.zimbra.common.mailbox.ContactConstants;
/*      */ import com.zimbra.common.service.ServiceException;
/*      */ import com.zimbra.common.service.ServiceException.Argument;
/*      */ import com.zimbra.common.util.BufferStream;
/*      */ import com.zimbra.common.util.ByteUtil;
/*      */ import com.zimbra.common.util.HttpUtil;
/*      */ import com.zimbra.common.util.HttpUtil.Browser;
/*      */ import com.zimbra.common.util.Log;
/*      */ import com.zimbra.common.util.StringUtil;
/*      */ import com.zimbra.common.util.ZimbraLog;
/*      */ import com.zimbra.cs.account.Account;
/*      */ import com.zimbra.cs.index.SortBy;
/*      */ import com.zimbra.cs.index.ZimbraHit;
/*      */ import com.zimbra.cs.index.ZimbraQueryResults;
/*      */ import com.zimbra.cs.mailbox.ACL;
/*      */ import com.zimbra.cs.mailbox.Appointment;
/*      */ import com.zimbra.cs.mailbox.CalendarItem;
/*      */ import com.zimbra.cs.mailbox.CalendarItem.AlarmData;
/*      */ import com.zimbra.cs.mailbox.Chat;
/*      */ import com.zimbra.cs.mailbox.Contact;
/*      */ import com.zimbra.cs.mailbox.Conversation;
/*      */ import com.zimbra.cs.mailbox.DeliveryOptions;
/*      */ import com.zimbra.cs.mailbox.Document;
/*      */ import com.zimbra.cs.mailbox.Flag;
/*      */ import com.zimbra.cs.mailbox.Flag.FlagInfo;
/*      */ import com.zimbra.cs.mailbox.Folder;
/*      */ import com.zimbra.cs.mailbox.Folder.FolderOptions;
/*      */ import com.zimbra.cs.mailbox.MailItem;
/*      */ import com.zimbra.cs.mailbox.MailItem.Type;
/*      */ import com.zimbra.cs.mailbox.MailItem.UnderlyingData;
/*      */ import com.zimbra.cs.mailbox.MailServiceException;
/*      */ import com.zimbra.cs.mailbox.MailServiceException.NoSuchItemException;
/*      */ import com.zimbra.cs.mailbox.Mailbox;
/*      */ import com.zimbra.cs.mailbox.Mailbox.SetCalendarItemData;
/*      */ import com.zimbra.cs.mailbox.MailboxIndex;
/*      */ import com.zimbra.cs.mailbox.MailboxMaintenance;
/*      */ import com.zimbra.cs.mailbox.MailboxManager;
/*      */ import com.zimbra.cs.mailbox.Message;
/*      */ import com.zimbra.cs.mailbox.Message.CalendarItemInfo;
/*      */ import com.zimbra.cs.mailbox.Mountpoint;
/*      */ import com.zimbra.cs.mailbox.Note;
/*      */ import com.zimbra.cs.mailbox.OperationContext;
/*      */ import com.zimbra.cs.mailbox.SearchFolder;
/*      */ import com.zimbra.cs.mailbox.Tag;
/*      */ import com.zimbra.cs.mailbox.Task;
/*      */ import com.zimbra.cs.mailbox.WikiItem;
/*      */ import com.zimbra.cs.mailbox.calendar.IcsImportParseHandler;
/*      */ import com.zimbra.cs.mailbox.calendar.IcsImportParseHandler.ImportInviteVisitor;
/*      */ import com.zimbra.cs.mailbox.calendar.Invite;
/*      */ import com.zimbra.cs.mailbox.util.TypedIdList;
/*      */ import com.zimbra.cs.mime.Mime;
/*      */ import com.zimbra.cs.mime.ParsedContact;
/*      */ import com.zimbra.cs.mime.ParsedMessage;
/*      */ import com.zimbra.cs.service.UserServletContext;
/*      */ import com.zimbra.cs.service.UserServletContext.Item;
/*      */ import com.zimbra.cs.service.UserServletException;
/*      */ import com.zimbra.cs.service.mail.ImportContacts;
/*      */ import com.zimbra.cs.service.util.ItemData;
/*      */ import com.zimbra.cs.service.util.ItemId;
/*      */ import com.zimbra.cs.servlet.util.JettyUtil;
/*      */ import java.io.BufferedReader;
/*      */ import java.io.Closeable;
/*      */ import java.io.IOException;
/*      */ import java.io.InputStream;
/*      */ import java.io.InputStreamReader;
/*      */ import java.io.OutputStream;
/*      */ import java.io.StringWriter;
/*      */ import java.nio.charset.Charset;
/*      */ import java.nio.charset.CharsetEncoder;
/*      */ import java.text.DateFormat;
/*      */ import java.text.SimpleDateFormat;
/*      */ import java.util.ArrayList;
/*      */ import java.util.Arrays;
/*      */ import java.util.Collection;
/*      */ import java.util.Collections;
/*      */ import java.util.Comparator;
/*      */ import java.util.Date;
/*      */ import java.util.EnumSet;
/*      */ import java.util.HashMap;
/*      */ import java.util.HashSet;
/*      */ import java.util.Iterator;
/*      */ import java.util.LinkedList;
/*      */ import java.util.List;
/*      */ import java.util.Map;
/*      */ import java.util.Map.Entry;
/*      */ import java.util.Set;
/*      */ import java.util.regex.Matcher;
/*      */ import java.util.regex.Pattern;
/*      */ import javax.mail.internet.MimeMessage;
/*      */ import javax.mail.internet.MimePart;
/*      */ import javax.servlet.http.HttpServletResponse;
/*      */ 
/*      */ public abstract class ArchiveFormatter extends Formatter
/*      */ {
/*      */   private final Pattern ILLEGAL_FILE_CHARS;
/*      */   private final Pattern ILLEGAL_FOLDER_CHARS;
/*      */   
/*      */   public ArchiveFormatter()
/*      */   {
/*  111 */     this.ILLEGAL_FILE_CHARS = Pattern.compile("[\\/\\:\\*\\?\\\"\\<\\>\\|\\\000]");
/*  112 */     this.ILLEGAL_FOLDER_CHARS = Pattern.compile("[\\:\\*\\?\\\"\\<\\>\\|\\\000]"); }
/*  113 */   private static String UTF8 = "UTF-8";
/*  114 */   public static enum Resolve { Modify,  Replace,  Reset,  Skip;
/*      */     
/*      */     private Resolve() {} }
/*      */   
/*  118 */   public static final String PARAM_RESOLVE = "resolve"; private static final Set<String> BLE = Collections.unmodifiableSet(Sets.newHashSet(new String[] { "TAR", "ZIP", "TGZ", "A6P", "AC", "AS", "ACR", "ACTION", "AIR", "APP", "APP", "AWK", "BAT", "CGI", "CMD", "COM", "CSH", "DEK", "DLD", "DS", "EBM", "ESH", "EXE", "EZS", "FKY", "FRS", "FXP", "GADGET", "HMS", "HTA", "ICD", "INX", "IPF", "ISU", "JAR", "JS", "JSE", "JSX", "KIX", "LUA", "MCR", "MEM", "MPX", "MS", "MSI", "MST", "OBS", "PAF", "PEX", "PIF", "PRC", "PRG", "PVD", "PWC", "PY", "PYC", "PYO", "QPX", "RBX", "REG", "RGS", "ROX", "RPJ", "SCAR", "SCR", "SCRIPT", "SCT", "SHB", "SHS", "SPR", "TLB", "TMS", "U3P", "UDF", "VB", "VBE", "VBS", "VBSCRIPT", "WCM", "WPK", "WS", "WSF", "XQT" }));
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private static final class SortPath
/*      */     implements Comparator<MailItem>
/*      */   {
/*      */     public int compare(MailItem m1, MailItem m2)
/*      */     {
/*      */       try
/*      */       {
/*  132 */         int ret = m1.getPath().compareTo(m2.getPath());
/*  133 */         return ret == 0 ? m1.getName().compareTo(m2.getName()) : ret;
/*      */       } catch (Exception e) {}
/*  135 */       return 0;
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   public Set<MailItem.Type> getDefaultSearchTypes()
/*      */   {
/*  172 */     return SEARCH_FOR_EVERYTHING;
/*      */   }
/*      */   
/*  175 */   public boolean supportsSave() { return true; }
/*      */   
/*  177 */   protected boolean getDefaultMeta() { return true; }
/*      */   
/*      */ 
/*      */   protected abstract ArchiveInputStream getInputStream(UserServletContext paramUserServletContext, String paramString)
/*      */     throws IOException, ServiceException, UserServletException;
/*      */   
/*      */   protected abstract ArchiveOutputStream getOutputStream(UserServletContext paramUserServletContext, String paramString)
/*      */     throws IOException;
/*      */   
/*      */   public void formatCallback(UserServletContext context)
/*      */     throws IOException, ServiceException, UserServletException
/*      */   {
/*  189 */     disableJettyTimeout(context);
/*      */     
/*  191 */     HashMap<Integer, Integer> cnts = new HashMap();
/*      */     
/*  193 */     HashMap<Integer, String> fldrs = new HashMap();
/*  194 */     String emptyname = (String)context.params.get("emptyname");
/*  195 */     String ext = "." + getType();
/*  196 */     String filename = (String)context.params.get("filename");
/*  197 */     String lock = (String)context.params.get("lock");
/*  198 */     String query = context.getQueryString();
/*  199 */     Set<String> names = new HashSet(4096);
/*  200 */     Set<MailItem.Type> sysTypes = EnumSet.of(MailItem.Type.FOLDER, MailItem.Type.SEARCHFOLDER, MailItem.Type.TAG, MailItem.Type.FLAG, MailItem.Type.MOUNTPOINT);
/*      */     
/*  202 */     Set<MailItem.Type> searchTypes = EnumSet.of(MailItem.Type.MESSAGE, new MailItem.Type[] { MailItem.Type.CONTACT, MailItem.Type.DOCUMENT, MailItem.Type.WIKI, MailItem.Type.APPOINTMENT, MailItem.Type.TASK, MailItem.Type.CHAT, MailItem.Type.NOTE });
/*      */     
/*      */ 
/*  205 */     ArchiveOutputStream aos = null;
/*  206 */     String types = context.getTypesString();
/*  207 */     MailboxMaintenance maintenance = null;
/*      */     try {
/*  209 */       if ((filename == null) || (filename.equals(""))) {
/*  210 */         Date date = new Date();
/*  211 */         DateFormat df = DateFormat.getDateInstance(3);
/*  212 */         SimpleDateFormat sdf = new SimpleDateFormat(".H-m-s");
/*      */         
/*  214 */         if (context.hasPart()) {
/*  215 */           filename = "attachments";
/*      */         } else
/*  217 */           filename = context.targetMailbox.getAccountId() + '.' + df.format(date).replace('/', '-') + sdf.format(date);
/*      */       } else {
/*      */         int dot;
/*  220 */         if ((dot = filename.lastIndexOf('.')) != -1)
/*      */         {
/*  222 */           String userProvidedExtension = filename.substring(dot + 1);
/*  223 */           if (BLE.contains(userProvidedExtension.toUpperCase()))
/*  224 */             filename = filename.substring(0, dot);
/*      */         }
/*      */       }
/*  227 */       if (!filename.endsWith(ext)) {
/*  228 */         filename = filename + ext;
/*      */       }
/*  230 */       if ((emptyname != null) && (!emptyname.equals("")) && (!emptyname.endsWith(ext))) {
/*  231 */         emptyname = emptyname + ext;
/*      */       }
/*      */       
/*  234 */       context.resp.addHeader("Content-Disposition", HttpUtil.createContentDisposition(context.req, "attachment", filename));
/*      */       
/*  236 */       if (ext.equals(".tar")) {
/*  237 */         context.resp.setContentType("application/x-tar");
/*  238 */       } else if (ext.equals(".tgz")) {
/*  239 */         context.resp.setContentType("application/x-compressed-tar");
/*  240 */       } else if (ext.equals(".zip")) {
/*  241 */         context.resp.setContentType("application/zip");
/*      */       }
/*  243 */       if (!Strings.isNullOrEmpty(types)) {
/*      */         try {
/*  245 */           searchTypes = MailItem.Type.setOf(types);
/*      */         } catch (IllegalArgumentException e) {
/*  247 */           throw MailServiceException.INVALID_TYPE(e.getMessage());
/*      */         }
/*  249 */         sysTypes.clear();
/*      */         
/*      */ 
/*  252 */         searchTypes.remove(MailItem.Type.CONVERSATION);
/*      */       }
/*      */       
/*  255 */       if ((lock != null) && ((lock.equals("1")) || (lock.equals("t")) || (lock.equals("true")))) {
/*  256 */         maintenance = MailboxManager.getInstance().beginMaintenance(context.targetMailbox.getAccountId(), context.targetMailbox.getId());
/*      */       }
/*      */       
/*  259 */       Charset charset = context.getCharset();
/*  260 */       CharsetEncoder encoder = charset.newEncoder();
/*  261 */       ZimbraQueryResults results; boolean saveTargetFolder; if (context.requestedItems != null) {
/*      */         try {
/*  263 */           for (UserServletContext.Item item : context.requestedItems)
/*  264 */             aos = saveItem(context, item.mailItem, fldrs, cnts, item.versioned, aos, encoder, names);
/*      */         } catch (Exception e) {
/*  266 */           warn(e);
/*      */         }
/*  268 */       } else if ((context.target != null) && (!(context.target instanceof Folder))) {
/*      */         try {
/*  270 */           aos = saveItem(context, context.target, fldrs, cnts, false, aos, encoder, names);
/*      */         } catch (Exception e) {
/*  272 */           warn(e);
/*      */         }
/*      */       } else {
/*  275 */         results = null;
/*  276 */         saveTargetFolder = false;
/*      */         
/*  278 */         if ((context.target instanceof Folder)) {
/*  279 */           Folder f = (Folder)context.target;
/*      */           
/*  281 */           if (f.getId() != 1) {
/*  282 */             saveTargetFolder = true;
/*  283 */             query = "under:\"" + f.getPath() + "\"" + (query == null ? "" : new StringBuilder().append(" ").append(query).toString());
/*      */           }
/*      */         }
/*  286 */         String taskQuery = query;
/*  287 */         if (query == null) {
/*  288 */           query = "";
/*      */         }
/*  290 */         String calendarQuery = query;
/*  291 */         if (context.getStartTime() != -1L) {
/*  292 */           query = query + " after:" + context.getStartTime();
/*  293 */           calendarQuery = calendarQuery + " appt-start:>=" + context.getStartTime();
/*      */         }
/*  295 */         if (context.getEndTime() != -1L) {
/*  296 */           query = query + " before:" + context.getEndTime();
/*  297 */           calendarQuery = calendarQuery + " appt-end:<" + context.getEndTime();
/*      */         }
/*      */         
/*  300 */         if ((query == null) || (query.equals(""))) {
/*  301 */           SortPath sp = new SortPath();
/*      */           
/*  303 */           for (MailItem.Type type : sysTypes) {
/*  304 */             List<MailItem> items = context.targetMailbox.getItemList(context.opContext, type);
/*      */             
/*  306 */             Collections.sort(items, sp);
/*  307 */             for (MailItem item : items) {
/*  308 */               aos = saveItem(context, item, fldrs, cnts, false, aos, encoder, names);
/*      */             }
/*      */           }
/*  311 */           query = "is:local";
/*      */         }
/*  313 */         Map<Set<MailItem.Type>, String> typesMap = new HashMap();
/*  314 */         typesMap.put(searchTypes, query);
/*  315 */         if ((context.getStartTime() != -1L) || (context.getEndTime() != -1L)) {
/*  316 */           if (searchTypes.contains(MailItem.Type.APPOINTMENT)) {
/*  317 */             searchTypes.remove(MailItem.Type.APPOINTMENT);
/*  318 */             Set<MailItem.Type> calendarTypes = new HashSet();
/*  319 */             calendarTypes.add(MailItem.Type.APPOINTMENT);
/*  320 */             typesMap.put(calendarTypes, calendarQuery);
/*      */           }
/*  322 */           if (searchTypes.contains(MailItem.Type.TASK)) {
/*  323 */             searchTypes.remove(MailItem.Type.TASK);
/*  324 */             Set<MailItem.Type> taskTypes = new HashSet();
/*  325 */             taskTypes.add(MailItem.Type.TASK);
/*  326 */             typesMap.put(taskTypes, StringUtil.isNullOrEmpty(taskQuery) ? "is:local" : taskQuery);
/*      */           }
/*      */         }
/*  329 */         for (Map.Entry<Set<MailItem.Type>, String> entry : typesMap.entrySet()) {
/*  330 */           results = context.targetMailbox.index.search(context.opContext, (String)entry.getValue(), (Set)entry.getKey(), SortBy.NONE, LC.zimbra_archive_formatter_search_chunk_size.intValue());
/*      */           
/*      */           try
/*      */           {
/*  334 */             while (results.hasNext()) {
/*  335 */               if (saveTargetFolder) {
/*  336 */                 saveTargetFolder = false;
/*  337 */                 aos = saveItem(context, context.target, fldrs, cnts, false, aos, encoder, names);
/*      */               }
/*  339 */               aos = saveItem(context, results.getNext().getMailItem(), fldrs, cnts, false, aos, encoder, names);
/*      */             }
/*  341 */             Closeables.closeQuietly(results);
/*  342 */             results = null;
/*      */           } catch (Exception e) {
/*  344 */             warn(e);
/*      */           } finally {
/*  346 */             Closeables.closeQuietly(results);
/*      */           }
/*      */         }
/*      */       }
/*  350 */       if (aos == null) {
/*  351 */         if (emptyname == null) {
/*  352 */           context.resp.setHeader("Content-Disposition", null);
/*  353 */           throw new UserServletException(204, "No data found");
/*      */         }
/*  355 */         context.resp.setHeader("Content-Disposition", HttpUtil.createContentDisposition(context.req, "attachment", emptyname));
/*  356 */         aos = getOutputStream(context, UTF8);
/*      */       }
/*      */       return;
/*  359 */     } finally { if (maintenance != null) {
/*  360 */         MailboxManager.getInstance().endMaintenance(maintenance, true, true);
/*      */       }
/*  362 */       if (aos != null) {
/*      */         try {
/*  364 */           aos.close();
/*      */         }
/*      */         catch (Exception e) {}
/*      */       }
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private void disableJettyTimeout(UserServletContext context)
/*      */   {
/*  390 */     if (LC.zimbra_archive_formatter_disable_timeout.booleanValue()) {
/*  391 */       JettyUtil.setIdleTimeout(0L, context.req);
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   private ArchiveOutputStream saveItem(UserServletContext context, MailItem mi, Map<Integer, String> fldrs, Map<Integer, Integer> cnts, boolean version, ArchiveOutputStream aos, CharsetEncoder charsetEncoder, Set<String> names)
/*      */     throws ServiceException
/*      */   {
/*  400 */     String ext = null;String name = null;
/*  401 */     String extra = null;
/*  402 */     Integer fid = Integer.valueOf(mi.getFolderId());
/*      */     
/*  404 */     InputStream is = null;
/*  405 */     String metaParam = (String)context.params.get("meta");
/*  406 */     boolean meta = !metaParam.equals("0") ? true : metaParam == null ? getDefaultMeta() : false;
/*      */     
/*  408 */     if ((!version) && (mi.isTagged(Flag.FlagInfo.VERSIONED))) {
/*  409 */       for (MailItem rev : context.targetMailbox.getAllRevisions(context.opContext, mi.getId(), mi.getType())) {
/*  410 */         if (mi.getVersion() != rev.getVersion())
/*  411 */           aos = saveItem(context, rev, fldrs, cnts, true, aos, charsetEncoder, names);
/*      */       }
/*      */     }
/*  414 */     switch (mi.getType()) {
/*      */     case APPOINTMENT: 
/*  416 */       Appointment appt = (Appointment)mi;
/*      */       
/*  418 */       if ((!appt.isPublic()) && (!appt.allowPrivateAccess(context.getAuthAccount(), context.isUsingAdminPrivileges()))) {
/*  419 */         return aos;
/*      */       }
/*  421 */       if (meta) {
/*  422 */         name = appt.getSubject();
/*  423 */         ext = "appt";
/*      */       } else {
/*  425 */         ext = "ics";
/*      */       }
/*  427 */       break;
/*      */     
/*      */     case CHAT: 
/*  430 */       ext = "chat";
/*  431 */       break;
/*      */     
/*      */     case CONTACT: 
/*  434 */       Contact ct = (Contact)mi;
/*      */       
/*  436 */       name = ct.getFileAsString();
/*  437 */       if (!meta) {
/*  438 */         ext = "vcf";
/*      */       }
/*      */       
/*      */       break;
/*      */     case FLAG: 
/*  443 */       return aos;
/*      */     
/*      */     case FOLDER: 
/*      */     case MOUNTPOINT: 
/*      */     case SEARCHFOLDER: 
/*  448 */       if (mi.getId() == 11) {
/*  449 */         name = "ROOT";
/*  450 */       } else if (mi.getId() == 1) {
/*  451 */         name = "USER_ROOT";
/*      */       } else {
/*  453 */         name = mi.getName();
/*      */       }
/*  455 */       break;
/*      */     
/*      */     case MESSAGE: 
/*  458 */       Message msg = (Message)mi;
/*      */       
/*  460 */       if (msg.hasCalendarItemInfos()) {
/*  461 */         Set<ItemId> calItems = Sets.newHashSet();
/*      */         
/*  463 */         for (Iterator<Message.CalendarItemInfo> it = msg.getCalendarItemInfoIterator(); it.hasNext();) {
/*  464 */           ItemId iid = ((Message.CalendarItemInfo)it.next()).getCalendarItemId();
/*  465 */           if (iid != null) {
/*  466 */             calItems.add(iid);
/*      */           }
/*      */         }
/*  469 */         for (ItemId i : calItems) {
/*  470 */           if (extra == null) {
/*  471 */             extra = "calendar=" + i.toString();
/*      */           } else {
/*  473 */             extra = extra + ',' + i.toString();
/*      */           }
/*      */         }
/*      */       }
/*  477 */       ext = "eml";
/*  478 */       break;
/*      */     
/*      */     case NOTE: 
/*  481 */       ext = "note";
/*  482 */       break;
/*      */     
/*      */     case TASK: 
/*  485 */       Task task = (Task)mi;
/*  486 */       if ((!task.isPublic()) && (!task.allowPrivateAccess(context.getAuthAccount(), context.isUsingAdminPrivileges()))) {
/*  487 */         return aos;
/*      */       }
/*  489 */       ext = "task";
/*  490 */       break;
/*      */     
/*      */     case VIRTUAL_CONVERSATION: 
/*  493 */       return aos;
/*      */     
/*      */     case WIKI: 
/*  496 */       ext = "wiki";
/*      */     }
/*      */     
/*      */     
/*  500 */     String fldr = (String)fldrs.get(fid);
/*  501 */     if (fldr == null) {
/*  502 */       Folder f = mi.getMailbox().getFolderById(context.opContext, fid.intValue());
/*      */       
/*  504 */       cnts.put(fid, Integer.valueOf(1));
/*  505 */       fldr = f.getPath();
/*  506 */       if (fldr.startsWith("/")) {
/*  507 */         fldr = fldr.substring(1);
/*      */       }
/*  509 */       fldr = sanitize(fldr, charsetEncoder);
/*  510 */       fldr = this.ILLEGAL_FOLDER_CHARS.matcher(fldr).replaceAll("_");
/*  511 */       fldrs.put(fid, fldr);
/*  512 */     } else if (!(mi instanceof Folder)) {
/*  513 */       int BATCH = 500;
/*  514 */       int cnt = ((Integer)cnts.get(fid)).intValue() + 1;
/*      */       
/*  516 */       cnts.put(fid, Integer.valueOf(cnt));
/*  517 */       cnt /= 500;
/*  518 */       if (cnt > 0) {
/*  519 */         fldr = fldr + '!' + cnt;
/*      */       }
/*      */     }
/*      */     
/*  523 */     int targetBaseLength = 0;
/*  524 */     if (context.noHierarchy())
/*      */     {
/*      */ 
/*  527 */       String targetPath = null;
/*  528 */       if (context.itemPath.endsWith("/")) {
/*  529 */         targetPath = context.itemPath.substring(0, context.itemPath.lastIndexOf("/"));
/*      */       } else {
/*  531 */         targetPath = context.itemPath;
/*      */       }
/*  533 */       targetBaseLength = targetPath.lastIndexOf('/');
/*  534 */       if (targetBaseLength >= fldr.length()) {
/*  535 */         fldr = "";
/*  536 */       } else if (targetBaseLength > 0) {
/*  537 */         fldr = fldr.substring(targetBaseLength + 1);
/*      */       }
/*      */     }
/*      */     try
/*      */     {
/*  542 */       byte[] data = null;
/*  543 */       String path = (mi instanceof Contact) ? getEntryName(mi, fldr, name, ext, charsetEncoder, names) : getEntryName(mi, fldr, name, ext, charsetEncoder, !(mi instanceof Document));
/*      */       
/*  545 */       long miSize = mi.getSize();
/*      */       
/*  547 */       if ((miSize == 0L) && (mi.getDigest() != null)) {
/*  548 */         ZimbraLog.misc.debug("blob db size 0 for item %d", new Object[] { Integer.valueOf(mi.getId()) });
/*  549 */         return aos;
/*      */       }
/*      */       ArchiveOutputStream localArchiveOutputStream2;
/*  552 */       try { is = mi.getContentStream();
/*      */       } catch (Exception e) {
/*  554 */         ZimbraLog.misc.error("missing blob for item %d: expected %d", new Object[] { Integer.valueOf(mi.getId()), Long.valueOf(miSize) });
/*  555 */         return aos;
/*      */       }
/*  557 */       if (aos == null) {
/*  558 */         aos = getOutputStream(context, charsetEncoder.charset().name());
/*      */       }
/*      */       
/*  561 */       if (((mi instanceof CalendarItem)) && ((context.getStartTime() != -1L) || (context.getEndTime() != -1L))) {
/*  562 */         Object instances = ((CalendarItem)mi).expandInstances(context.getStartTime(), context.getEndTime(), false);
/*  563 */         if (((Collection)instances).isEmpty()) {
/*  564 */           return aos;
/*      */         }
/*      */       }
/*      */       
/*  568 */       ArchiveOutputEntry aoe = aos.newOutputEntry(path + ".meta", mi.getType().toString(), mi.getType().toByte(), mi.getDate());
/*  569 */       if (((mi instanceof Message)) && ((mi.getFlagBitmask() & Flag.ID_UNREAD) != 0)) {
/*  570 */         aoe.setUnread();
/*      */       }
/*  572 */       if (meta) {
/*  573 */         ItemData itemData = new ItemData(mi, extra);
/*  574 */         if (context.noHierarchy())
/*      */         {
/*      */ 
/*  577 */           if ((targetBaseLength > 0) && (targetBaseLength + 1 < itemData.path.length())) {
/*  578 */             itemData.path = itemData.path.substring(targetBaseLength + 1);
/*      */           }
/*      */         }
/*  581 */         byte[] metaData = itemData.encode();
/*      */         
/*  583 */         aoe.setSize(metaData.length);
/*  584 */         aos.putNextEntry(aoe);
/*  585 */         aos.write(metaData);
/*  586 */         aos.closeEntry();
/*  587 */       } else if ((mi instanceof CalendarItem)) {
/*  588 */         HttpUtil.Browser browser = HttpUtil.guessBrowser(context.req);
/*  589 */         Object calItems = new ArrayList();
/*  590 */         boolean needAppleICalHacks = HttpUtil.Browser.APPLE_ICAL.equals(browser);
/*  591 */         boolean useOutlookCompatMode = HttpUtil.Browser.IE.equals(browser);
/*  592 */         OperationContext octxt = new OperationContext(context.getAuthAccount(), context.isUsingAdminPrivileges());
/*  593 */         StringWriter writer = new StringWriter();
/*  594 */         ((List)calItems).add((CalendarItem)mi);
/*  595 */         context.targetMailbox.writeICalendarForCalendarItems(writer, octxt, (Collection)calItems, useOutlookCompatMode, true, needAppleICalHacks, true);
/*      */         
/*      */ 
/*  598 */         data = writer.toString().getBytes(charsetEncoder.charset());
/*  599 */       } else if ((mi instanceof Contact)) {
/*  600 */         VCard vcf = VCard.formatContact((Contact)mi);
/*  601 */         data = vcf.getFormatted().getBytes(charsetEncoder.charset());
/*  602 */       } else if (((mi instanceof Message)) && 
/*  603 */         (context.hasPart())) {
/*  604 */         MimeMessage mm = ((Message)mi).getMimeMessage();
/*  605 */         Object attachmentNames = new HashSet();
/*  606 */         for (String part : context.getPart().split(","))
/*      */         {
/*  608 */           MimePart mp = Mime.getMimePart(mm, part);
/*      */           
/*      */ 
/*  611 */           if (mp == null) {
/*  612 */             throw MailServiceException.NO_SUCH_PART(part);
/*      */           }
/*  614 */           name = Mime.getFilename(mp);
/*  615 */           ext = null;
/*  616 */           long sz = mp.getSize();
/*  617 */           if (sz == -1L) {
/*  618 */             sz = miSize;
/*      */           }
/*  620 */           if (name == null) {
/*  621 */             name = "attachment";
/*      */           } else {
/*  623 */             int dot = name.lastIndexOf('.');
/*      */             
/*  625 */             if ((dot != -1) && (dot < name.length() - 1)) {
/*  626 */               ext = name.substring(dot + 1);
/*  627 */               name = name.substring(0, dot);
/*      */             }
/*      */           }
/*  630 */           BufferStream bs = new BufferStream(sz, 1048576);
/*  631 */           InputStream stream = mp.getInputStream();
/*      */           try {
/*  633 */             bs.readFrom(stream);
/*      */           }
/*      */           finally {}
/*      */           
/*      */ 
/*  638 */           aoe = aos.newOutputEntry(getEntryName(mi, "", name, ext, charsetEncoder, (Set)attachmentNames), mi.getType().toString(), mi.getType().toByte(), mi.getDate());
/*      */           
/*      */ 
/*  641 */           sz = bs.getSize();
/*  642 */           aoe.setSize(sz);
/*  643 */           aos.putNextEntry(aoe);
/*  644 */           bs.copyTo(aos.getOutputStream());
/*  645 */           bs.close();
/*  646 */           aos.closeEntry();
/*      */         }
/*  648 */         return aos;
/*      */       }
/*      */       
/*  651 */       aoe = aos.newOutputEntry(path, mi.getType().toString(), mi.getType().toByte(), mi.getDate());
/*  652 */       if (data != null) {
/*  653 */         aoe.setSize(data.length);
/*  654 */         aos.putNextEntry(aoe);
/*  655 */         aos.write(data);
/*  656 */         aos.closeEntry();
/*  657 */       } else if (is != null) {
/*  658 */         if (context.shouldReturnBody()) {
/*  659 */           byte[] buf = new byte[aos.getRecordSize() * 20];
/*      */           
/*  661 */           long remain = miSize;
/*      */           
/*  663 */           aoe.setSize(miSize);
/*  664 */           aos.putNextEntry(aoe);
/*  665 */           int in; while ((remain > 0L) && ((in = is.read(buf)) >= 0)) {
/*  666 */             aos.write(buf, 0, remain < in ? (int)remain : in);
/*  667 */             remain -= in;
/*      */           }
/*  669 */           if (remain != 0L) {
/*  670 */             ZimbraLog.misc.error("mismatched blob size for item %d: expected %d", new Object[] { Integer.valueOf(mi.getId()), Long.valueOf(miSize) });
/*  671 */             if (remain > 0L) {
/*  672 */               Arrays.fill(buf, (byte)32);
/*  673 */               while (remain > 0L) {
/*  674 */                 aos.write(buf, 0, remain < buf.length ? (int)remain : buf.length);
/*  675 */                 remain -= buf.length;
/*      */               }
/*      */             }
/*  678 */             aos.closeEntry();
/*  679 */             aoe = aos.newOutputEntry(path + ".err", mi.getType().toString(), mi.getType().toByte(), mi.getDate());
/*  680 */             aoe.setSize(0L);
/*  681 */             aos.putNextEntry(aoe);
/*      */           }
/*      */         }
/*      */         else {
/*  685 */           byte[] headerData = HeadersOnlyInputStream.getHeaders(is);
/*      */           
/*  687 */           aoe.setSize(headerData.length);
/*  688 */           aos.putNextEntry(aoe);
/*  689 */           aos.write(headerData);
/*      */         }
/*  691 */         aos.closeEntry();
/*      */       }
/*      */     } catch (Exception e) {
/*  694 */       throw ServiceException.FAILURE("archive error", e);
/*      */     } finally {
/*  696 */       ByteUtil.closeStream(is);
/*      */     }
/*  698 */     return aos;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */   private String getEntryName(MailItem mi, String fldr, String name, String ext, CharsetEncoder encoder, Set<String> names)
/*      */   {
/*  706 */     String path = getEntryName(mi, fldr, name, ext, encoder, false);
/*  707 */     int counter = 0;
/*      */     String lpath;
/*      */     do {
/*  710 */       path = fldr + '/' + name;
/*  711 */       if (counter > 0) {
/*  712 */         path = path + String.format("-%02d", new Object[] { Integer.valueOf(counter) });
/*      */       }
/*  714 */       if (ext != null) {
/*  715 */         path = path + '.' + ext;
/*      */       }
/*  717 */       counter++;
/*  718 */       lpath = path.toLowerCase();
/*  719 */     } while (names.contains(lpath));
/*  720 */     names.add(lpath);
/*  721 */     return path;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private String getEntryName(MailItem mi, String fldr, String name, String ext, CharsetEncoder encoder, boolean prefix)
/*      */   {
/*  730 */     if (Strings.isNullOrEmpty(name)) {
/*  731 */       name = mi.getName();
/*      */     }
/*  733 */     if (Strings.isNullOrEmpty(name)) {
/*  734 */       name = mi.getSubject();
/*      */     }
/*  736 */     if ((prefix) && (!Strings.isNullOrEmpty(name))) {
/*  737 */       name = Strings.padStart(new StringBuilder().append(mi.getId()).append("").toString(), 10, '0') + "-" + sanitize(name, encoder);
/*      */     }
/*      */     
/*  740 */     if (Strings.isNullOrEmpty(name)) {
/*  741 */       name = mi.getType().toString() + '-' + mi.getId();
/*  742 */     } else if (name.length() > 121) {
/*  743 */       name = name.substring(0, 120);
/*      */     }
/*  745 */     if (mi.isTagged(Flag.FlagInfo.VERSIONED))
/*      */     {
/*  747 */       int dot = name.lastIndexOf('.');
/*  748 */       if ((dot >= 0) && (dot >= name.length() - 5)) {
/*  749 */         name = name.substring(0, dot) + String.format("-%05d", new Object[] { Integer.valueOf(mi.getVersion()) }) + name.substring(dot);
/*      */       } else {
/*  751 */         name = name + String.format("-%05d", new Object[] { Integer.valueOf(mi.getVersion()) });
/*      */       }
/*      */     }
/*  754 */     name = this.ILLEGAL_FILE_CHARS.matcher(name).replaceAll("_").trim();
/*  755 */     while (name.endsWith(".")) {
/*  756 */       name = name.substring(0, name.length() - 1).trim();
/*      */     }
/*  758 */     String path = fldr + '/' + name;
/*  759 */     if (ext != null) {
/*  760 */       path = path + '.' + ext;
/*      */     }
/*  762 */     return path;
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */   public void saveCallback(UserServletContext context, String contentType, Folder fldr, String file)
/*      */     throws IOException, ServiceException
/*      */   {
/*  770 */     disableJettyTimeout(context);
/*      */     
/*  772 */     Exception ex = null;
/*  773 */     ItemData id = null;
/*  774 */     Map<String, Integer> digestMap = new HashMap();
/*  775 */     List<ServiceException> errs = new LinkedList();
/*      */     
/*  777 */     Map<Object, Folder> fmap = new HashMap();
/*  778 */     Map<Integer, Integer> idMap = new HashMap();
/*  779 */     long last = System.currentTimeMillis();
/*  780 */     String types = context.getTypesString();
/*  781 */     String resolve = (String)context.params.get("resolve");
/*  782 */     String subfolder = (String)context.params.get("subfolder");
/*  783 */     String timestamp = (String)context.params.get("timestamp");
/*  784 */     String timeout = (String)context.params.get("timeout");
/*      */     
/*      */     try
/*      */     {
/*  788 */       int[] ids = null;
/*  789 */       long interval = 45000L;
/*  790 */       Resolve r = resolve == null ? Resolve.Skip : Resolve.valueOf(resolve.substring(0, 1).toUpperCase() + resolve.substring(1).toLowerCase());
/*  791 */       if (timeout != null) {
/*  792 */         interval = Long.parseLong(timeout);
/*      */       }
/*  794 */       Set<MailItem.Type> searchTypes = null;
/*      */       
/*  796 */       if (context.reqListIds != null) {
/*  797 */         ids = (int[])context.reqListIds.clone();
/*  798 */         Arrays.sort(ids);
/*      */       }
/*  800 */       if (!Strings.isNullOrEmpty(types)) {
/*      */         try {
/*  802 */           searchTypes = MailItem.Type.setOf(types);
/*      */         } catch (IllegalArgumentException e) {
/*  804 */           throw MailServiceException.INVALID_TYPE(e.getMessage());
/*      */         }
/*  806 */         searchTypes.remove(MailItem.Type.CONVERSATION);
/*      */       }
/*  808 */       Charset charset = context.getCharset();
/*      */       ArchiveInputStream ais;
/*  810 */       try { ais = getInputStream(context, charset.name());
/*      */       } catch (Exception e) {
/*  812 */         String filename = (String)context.params.get("uploadName");
/*  813 */         throw FormatterServiceException.INVALID_FORMAT(filename == null ? "unknown" : filename);
/*      */       }
/*  815 */       if (!Strings.isNullOrEmpty(subfolder)) {
/*  816 */         fldr = createPath(context, fmap, fldr.getPath() + subfolder, MailItem.Type.UNKNOWN);
/*      */       }
/*  818 */       List<Folder> flist = fldr.getSubfolderHierarchy();
/*  819 */       if (r == Resolve.Reset) {
/*  820 */         for (Folder f : flist) {
/*  821 */           if (!context.targetMailbox.isImmutableSystemFolder(f.getId()))
/*      */             try
/*      */             {
/*      */               List<Integer> delIds;
/*      */               
/*      */ 
/*      */ 
/*      */ 
/*      */               List<Integer> delIds;
/*      */               
/*      */ 
/*      */ 
/*  833 */               if (searchTypes == null) {
/*  834 */                 delIds = context.targetMailbox.listItemIds(context.opContext, MailItem.Type.UNKNOWN, f.getId());
/*      */               } else {
/*  836 */                 delIds = context.targetMailbox.getItemIds(context.opContext, f.getId()).getIds(searchTypes);
/*      */               }
/*  838 */               if (delIds != null)
/*      */               {
/*      */ 
/*  841 */                 int[] delIdsArray = new int[delIds.size()];
/*  842 */                 int i = 0;
/*      */                 
/*  844 */                 for (Integer del : delIds) {
/*  845 */                   if (del.intValue() >= 256) {
/*  846 */                     delIdsArray[(i++)] = del.intValue();
/*      */                   }
/*      */                 }
/*  849 */                 while (i < delIds.size()) {
/*  850 */                   delIdsArray[(i++)] = -1;
/*      */                 }
/*  852 */                 context.targetMailbox.delete(context.opContext, delIdsArray, MailItem.Type.UNKNOWN, null);
/*      */               }
/*  854 */             } catch (MailServiceException e) { if (e.getCode() != "mail.NO_SUCH_FOLDER") {
/*  855 */                 r = Resolve.Replace;
/*  856 */                 addError(errs, e);
/*      */               }
/*      */             } catch (Exception e) {
/*  859 */               r = Resolve.Replace;
/*  860 */               addError(errs, FormatterServiceException.UNKNOWN_ERROR(f.getName(), e));
/*      */             }
/*      */         }
/*  863 */         context.targetMailbox.purge(MailItem.Type.UNKNOWN);
/*  864 */         flist = fldr.getSubfolderHierarchy();
/*      */       }
/*  866 */       for (Folder f : flist) {
/*  867 */         fmap.put(Integer.valueOf(f.getId()), f);
/*  868 */         fmap.put(f.getPath(), f);
/*      */       }
/*      */       try
/*      */       {
/*  872 */         Boolean meta = Boolean.valueOf(false);
/*      */         ArchiveInputEntry aie;
/*  874 */         while ((aie = ais.getNextEntry()) != null)
/*      */         {
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*  881 */           if (!aie.getName().startsWith("__MACOSX/"))
/*      */           {
/*  883 */             if (aie.getName().endsWith(".meta")) {
/*  884 */               meta = Boolean.valueOf(true);
/*  885 */               if (id != null) {
/*  886 */                 addItem(context, fldr, fmap, digestMap, idMap, ids, searchTypes, r, id, ais, null, errs);
/*      */               }
/*      */               try {
/*  889 */                 id = new ItemData(readArchiveEntry(ais, aie));
/*      */               } catch (Exception e) {
/*  891 */                 addError(errs, FormatterServiceException.INVALID_FORMAT(aie.getName()));
/*      */               }
/*      */             } else {
/*  894 */               if (aie.getName().endsWith(".err")) {
/*  895 */                 addError(errs, FormatterServiceException.MISMATCHED_SIZE(aie.getName()));
/*  896 */               } else if (id == null) {
/*  897 */                 if (meta.booleanValue()) {
/*  898 */                   addError(errs, FormatterServiceException.MISSING_META(aie.getName()));
/*      */                 } else {
/*  900 */                   addData(context, fldr, fmap, searchTypes, r, (timestamp == null) || (!timestamp.equals("0")), ais, aie, errs);
/*      */                 }
/*      */               }
/*  903 */               else if (((aie.getType() != 0) && (id.ud.type != aie.getType())) || ((id.ud.getBlobDigest() != null) && (aie.getSize() != -1L) && (id.ud.size != aie.getSize()))) {
/*  904 */                 addError(errs, FormatterServiceException.MISMATCHED_META(aie.getName()));
/*      */               } else {
/*  906 */                 addItem(context, fldr, fmap, digestMap, idMap, ids, searchTypes, r, id, ais, aie, errs);
/*      */               }
/*  908 */               id = null;
/*      */             } } }
/*  910 */         if (id != null) {
/*  911 */           addItem(context, fldr, fmap, digestMap, idMap, ids, searchTypes, r, id, ais, null, errs);
/*      */         }
/*      */       } catch (Exception e) {
/*  914 */         if (id == null) {
/*  915 */           addError(errs, FormatterServiceException.UNKNOWN_ERROR(e));
/*      */         } else {
/*  917 */           addError(errs, FormatterServiceException.UNKNOWN_ERROR(id.path, e));
/*      */         }
/*  919 */         id = null;
/*      */       } finally {
/*  921 */         if (ais != null) {
/*  922 */           ais.close();
/*      */         }
/*      */       }
/*      */     } catch (Exception e) {
/*  926 */       ex = e;
/*      */     }
/*      */     try {
/*  929 */       updateClient(context, ex, errs);
/*      */     } catch (ServiceException e) {
/*  931 */       throw e;
/*      */     } catch (Exception e) {
/*  933 */       throw ServiceException.FAILURE("Archive formatter failure", e);
/*      */     }
/*      */   }
/*      */   
/*      */   private void addError(List<ServiceException> errs, ServiceException ex) {
/*  938 */     StringBuilder s = new StringBuilder(ex.getLocalizedMessage() == null ? ex.toString() : ex.getLocalizedMessage());
/*      */     
/*  940 */     errs.add(ex);
/*  941 */     if (!ex.getArgs().isEmpty()) {
/*  942 */       s.append(':');
/*  943 */       for (ServiceException.Argument arg : ex.getArgs()) {
/*  944 */         s.append(' ').append(arg.name).append('=').append(arg.value);
/*      */       }
/*      */     }
/*  947 */     ZimbraLog.misc.warn(s, ex);
/*      */   }
/*      */   
/*      */   private Folder createParent(UserServletContext context, Map<Object, Folder> fmap, String path, MailItem.Type view) throws ServiceException
/*      */   {
/*  952 */     String parent = path.substring(0, path.lastIndexOf('/'));
/*  953 */     if (parent.equals("")) {
/*  954 */       parent = "/";
/*      */     }
/*  956 */     return createPath(context, fmap, parent, view);
/*      */   }
/*      */   
/*      */   private Folder createPath(UserServletContext context, Map<Object, Folder> fmap, String path, MailItem.Type view)
/*      */     throws ServiceException
/*      */   {
/*      */     Folder fldr;
/*  963 */     if ((fldr = (Folder)fmap.get(path)) == null) {
/*      */       try {
/*  965 */         fldr = context.targetMailbox.getFolderByPath(context.opContext, path);
/*      */       } catch (Exception e) {
/*  967 */         fldr = context.targetMailbox.createFolder(context.opContext, path, new Folder.FolderOptions().setDefaultView(view));
/*      */       }
/*  969 */       fmap.put(Integer.valueOf(fldr.getId()), fldr);
/*  970 */       fmap.put(fldr.getPath(), fldr);
/*      */     }
/*  972 */     if ((view != MailItem.Type.UNKNOWN) && (fldr.getDefaultView() != MailItem.Type.UNKNOWN) && (fldr.getDefaultView() != view) && (((view != MailItem.Type.DOCUMENT) && (view != MailItem.Type.WIKI)) || ((fldr.getDefaultView() != MailItem.Type.DOCUMENT) && (fldr.getDefaultView() != MailItem.Type.WIKI))))
/*      */     {
/*      */ 
/*  975 */       throw FormatterServiceException.INVALID_TYPE(view.toString(), path);
/*      */     }
/*  977 */     return fldr;
/*      */   }
/*      */   
/*  980 */   private static final String[] NO_TAGS = new String[0];
/*      */   
/*      */   @VisibleForTesting
/*      */   static String[] getTagNames(ItemData id) {
/*  984 */     if (Strings.isNullOrEmpty(id.tags)) {
/*  985 */       return NO_TAGS;
/*      */     }
/*  987 */     return ItemData.getTagNames(id.tags);
/*      */   }
/*      */   
/*      */   private static byte[] readArchiveEntry(ArchiveInputStream ais, ArchiveInputEntry aie) throws IOException
/*      */   {
/*  992 */     if (aie == null) {
/*  993 */       return null;
/*      */     }
/*      */     
/*  996 */     int dsz = (int)aie.getSize();
/*      */     
/*      */ 
/*  999 */     if (dsz == 0)
/* 1000 */       return null;
/* 1001 */     byte[] data; byte[] data; if (dsz == -1) {
/* 1002 */       data = ByteUtil.getContent(ais.getInputStream(), -1, false);
/*      */     } else {
/* 1004 */       data = new byte[dsz];
/* 1005 */       if (ais.read(data, 0, dsz) != dsz) {
/* 1006 */         throw new IOException("archive read err");
/*      */       }
/*      */     }
/* 1009 */     return data;
/*      */   }
/*      */   
/* 1012 */   private String string(String s) { return s == null ? new String() : s; }
/*      */   
/*      */   private void warn(Exception e) {
/* 1015 */     if (e.getCause() == null) {
/* 1016 */       ZimbraLog.misc.warn("Archive Formatter warning: %s", e, e);
/*      */     } else {
/* 1018 */       ZimbraLog.misc.warn("Archive Formatter warning: %s: %s", e, e.getCause().toString(), e.getCause());
/*      */     }
/*      */   }
/*      */   
/*      */   private void addItem(UserServletContext context, Folder fldr, Map<Object, Folder> fmap, Map<String, Integer> digestMap, Map<Integer, Integer> idMap, int[] ids, Set<MailItem.Type> types, Resolve r, ItemData id, ArchiveInputStream ais, ArchiveInputEntry aie, List<ServiceException> errs)
/*      */     throws ServiceException
/*      */   {
/*      */     try
/*      */     {
/* 1027 */       Mailbox mbox = fldr.getMailbox();
/* 1028 */       MailItem mi = MailItem.constructItem(mbox, id.ud);
/* 1029 */       MailItem newItem = null;MailItem oldItem = null;
/* 1030 */       OperationContext octxt = context.opContext;
/*      */       
/*      */ 
/* 1033 */       boolean root = (fldr.getId() == 11) || (fldr.getId() == 1) || (id.path.startsWith(fldr.getPath() + '/'));
/*      */       
/* 1035 */       if (((ids != null) && (Arrays.binarySearch(ids, id.ud.id) < 0)) || ((types != null) && (!types.contains(MailItem.Type.of(id.ud.type))))) {
/* 1036 */         return;
/*      */       }
/* 1038 */       if ((id.ud.getBlobDigest() != null) && (aie == null)) {
/* 1039 */         addError(errs, FormatterServiceException.MISSING_BLOB(id.path)); return; }
/*      */       String path;
/*      */       String path;
/* 1042 */       if (root) {
/* 1043 */         path = id.path;
/*      */       } else {
/* 1045 */         path = fldr.getPath() + id.path;
/*      */       }
/* 1047 */       if ((path.endsWith("/")) && (!path.equals("/"))) {
/* 1048 */         path = path.substring(0, path.length() - 1);
/*      */       }
/* 1050 */       if (mbox.isImmutableSystemFolder(id.ud.folderId)) {
/* 1051 */         return;
/*      */       }
/* 1053 */       switch (mi.getType()) {
/*      */       case APPOINTMENT: 
/*      */       case TASK: 
/* 1056 */         CalendarItem ci = (CalendarItem)mi;
/*      */         
/* 1058 */         fldr = createPath(context, fmap, path, ci.getType() == MailItem.Type.APPOINTMENT ? MailItem.Type.APPOINTMENT : MailItem.Type.TASK);
/* 1059 */         if ((!root) || (r != Resolve.Reset)) {
/* 1060 */           CalendarItem oldCI = null;
/*      */           try
/*      */           {
/* 1063 */             oldCI = mbox.getCalendarItemByUid(octxt, ci.getUid());
/*      */           }
/*      */           catch (Exception e) {}
/* 1066 */           if ((oldCI != null) && (r == Resolve.Replace)) {
/* 1067 */             mbox.delete(octxt, oldCI.getId(), oldCI.getType());
/*      */           } else {
/* 1069 */             oldItem = oldCI;
/*      */           }
/*      */         }
/* 1072 */         if ((oldItem == null) || (r != Resolve.Skip)) {
/* 1073 */           CalendarItem.AlarmData ad = ci.getAlarmData();
/* 1074 */           byte[] data = readArchiveEntry(ais, aie);
/* 1075 */           Map<Integer, MimeMessage> blobMimeMsgMap = data == null ? null : CalendarItem.decomposeBlob(data);
/* 1076 */           Mailbox.SetCalendarItemData defScid = new Mailbox.SetCalendarItemData();
/* 1077 */           Mailbox.SetCalendarItemData[] exceptionScids = null;
/* 1078 */           Invite[] invs = ci.getInvites();
/*      */           
/*      */ 
/* 1081 */           if ((invs != null) && (invs.length > 0)) {
/* 1082 */             defScid.invite = invs[0];
/* 1083 */             MimeMessage mm; if ((blobMimeMsgMap != null) && ((mm = (MimeMessage)blobMimeMsgMap.get(Integer.valueOf(defScid.invite.getMailItemId()))) != null))
/*      */             {
/* 1085 */               defScid.message = new ParsedMessage(mm, mbox.attachmentsIndexingEnabled());
/*      */             }
/* 1087 */             if (invs.length > 1) {
/* 1088 */               exceptionScids = new Mailbox.SetCalendarItemData[invs.length - 1];
/* 1089 */               for (int i = 1; i < invs.length; i++) {
/* 1090 */                 Mailbox.SetCalendarItemData scid = new Mailbox.SetCalendarItemData();
/*      */                 
/* 1092 */                 scid.invite = invs[i];
/* 1093 */                 MimeMessage mm; if ((blobMimeMsgMap != null) && ((mm = (MimeMessage)blobMimeMsgMap.get(Integer.valueOf(defScid.invite.getMailItemId()))) != null))
/*      */                 {
/* 1095 */                   scid.message = new ParsedMessage(mm, mbox.attachmentsIndexingEnabled());
/*      */                 }
/* 1097 */                 exceptionScids[(i - 1)] = scid;
/*      */               }
/*      */             }
/* 1100 */             newItem = mbox.setCalendarItem(octxt, (oldItem != null) && (r == Resolve.Modify) ? oldItem.getFolderId() : fldr.getId(), ci.getFlagBitmask(), ci.getTags(), defScid, exceptionScids, ci.getAllReplies(), ad == null ? 0L : ad.getNextAt());
/*      */           }
/*      */         }
/*      */         
/*      */ 
/* 1105 */         break;
/*      */       
/*      */ 
/*      */       case CHAT: 
/* 1109 */         Chat chat = (Chat)mi;
/* 1110 */         byte[] content = readArchiveEntry(ais, aie);
/* 1111 */         ParsedMessage pm = new ParsedMessage(content, Long.valueOf(mi.getDate()), mbox.attachmentsIndexingEnabled());
/* 1112 */         fldr = createPath(context, fmap, path, MailItem.Type.CHAT);
/* 1113 */         if ((root) && (r != Resolve.Reset)) {
/* 1114 */           Chat oldChat = null;
/*      */           try
/*      */           {
/* 1117 */             oldChat = mbox.getChatById(octxt, chat.getId());
/* 1118 */             if (oldChat.getFolderId() != fldr.getId()) {
/* 1119 */               oldChat = null;
/*      */             }
/*      */           }
/*      */           catch (Exception e) {}
/* 1123 */           if ((oldChat != null) && (chat.getSender().equals(oldChat.getSender())) && (chat.getSubject().equals(oldChat.getSubject())))
/*      */           {
/*      */ 
/* 1126 */             if (r == Resolve.Replace) {
/* 1127 */               mbox.delete(octxt, oldChat.getId(), oldChat.getType());
/*      */             } else {
/* 1129 */               oldItem = oldChat;
/* 1130 */               if (r == Resolve.Modify)
/* 1131 */                 newItem = mbox.updateChat(octxt, pm, oldItem.getId());
/*      */             }
/*      */           }
/*      */         }
/* 1135 */         if (oldItem == null) {
/* 1136 */           newItem = mbox.createChat(octxt, pm, fldr.getId(), chat.getFlagBitmask(), chat.getTags());
/*      */         }
/*      */         break;
/*      */       case CONVERSATION: 
/* 1140 */         Conversation cv = (Conversation)mi;
/*      */         
/* 1142 */         if ((r != Resolve.Reset) && (r != Resolve.Skip)) {
/*      */           try {
/* 1144 */             oldItem = mbox.getConversationByHash(octxt, Mailbox.getHash(cv.getSubject()));
/*      */           }
/*      */           catch (Exception e) {}
/*      */         }
/*      */         
/*      */         break;
/*      */       case CONTACT: 
/* 1151 */         Contact ct = (Contact)mi;
/*      */         
/* 1153 */         fldr = createPath(context, fmap, path, MailItem.Type.CONTACT);
/* 1154 */         if ((root) && (r != Resolve.Reset)) {
/* 1155 */           Contact oldContact = null;
/*      */           try
/*      */           {
/* 1158 */             oldContact = mbox.getContactById(octxt, ct.getId());
/* 1159 */             if (oldContact.getFolderId() != fldr.getId()) {
/* 1160 */               oldContact = null;
/*      */             }
/*      */           }
/*      */           catch (Exception e) {}
/*      */           
/* 1165 */           if (oldContact != null) {
/* 1166 */             String email = string(ct.get(ContactConstants.A_email));
/* 1167 */             String first = string(ct.get(ContactConstants.A_firstName));
/* 1168 */             String name = string(ct.get(ContactConstants.A_fullName));
/* 1169 */             String oldemail = string(oldContact.get(ContactConstants.A_email));
/* 1170 */             String oldfirst = string(oldContact.get(ContactConstants.A_firstName));
/* 1171 */             String oldname = string(oldContact.get(ContactConstants.A_fullName));
/*      */             
/* 1173 */             if ((email.equals(oldemail)) && (first.equals(oldfirst)) && (name.equals(oldname))) {
/* 1174 */               if (r == Resolve.Replace) {
/* 1175 */                 mbox.delete(octxt, oldContact.getId(), oldContact.getType());
/*      */               } else {
/* 1177 */                 oldItem = oldContact;
/* 1178 */                 if (r == Resolve.Modify) {
/* 1179 */                   mbox.modifyContact(octxt, oldItem.getId(), new ParsedContact(ct.getFields(), readArchiveEntry(ais, aie)));
/*      */                 }
/*      */               }
/*      */             }
/*      */           }
/*      */         }
/* 1185 */         if (oldItem == null) {
/* 1186 */           newItem = mbox.createContact(octxt, new ParsedContact(ct.getFields(), readArchiveEntry(ais, aie)), fldr.getId(), ct.getTags());
/*      */         }
/*      */         
/*      */ 
/*      */         break;
/*      */       case WIKI: 
/*      */       case DOCUMENT: 
/* 1193 */         Document doc = (Document)mi;
/* 1194 */         Document oldDoc = null;
/* 1195 */         Integer oldId = (Integer)idMap.get(Integer.valueOf(mi.getId()));
/*      */         
/* 1197 */         fldr = createParent(context, fmap, path, doc.getType() == MailItem.Type.DOCUMENT ? MailItem.Type.DOCUMENT : MailItem.Type.WIKI);
/* 1198 */         if (oldId == null) {
/*      */           try {
/* 1200 */             for (Document listDoc : mbox.getDocumentList(octxt, fldr.getId())) {
/* 1201 */               if (doc.getName().equals(listDoc.getName())) {
/* 1202 */                 oldDoc = listDoc;
/* 1203 */                 idMap.put(Integer.valueOf(doc.getId()), Integer.valueOf(oldDoc.getId()));
/* 1204 */                 break;
/*      */               }
/*      */             }
/*      */           }
/*      */           catch (Exception e) {}
/*      */         } else {
/* 1210 */           oldDoc = mbox.getDocumentById(octxt, oldId.intValue());
/*      */         }
/* 1212 */         if (oldDoc != null) {
/* 1213 */           if ((r == Resolve.Replace) && (oldId == null)) {
/* 1214 */             mbox.delete(octxt, oldDoc.getId(), oldDoc.getType());
/* 1215 */           } else { if (doc.getVersion() < oldDoc.getVersion()) {
/* 1216 */               return;
/*      */             }
/* 1218 */             oldItem = oldDoc;
/* 1219 */             if (doc.getVersion() > oldDoc.getVersion()) {
/* 1220 */               newItem = mbox.addDocumentRevision(octxt, oldDoc.getId(), doc.getCreator(), doc.getName(), doc.getDescription(), doc.isDescriptionEnabled(), ais.getInputStream());
/*      */             }
/*      */             
/*      */ 
/* 1224 */             if (r != Resolve.Skip) {
/* 1225 */               mbox.setDate(octxt, oldDoc.getId(), doc.getType(), doc.getDate());
/*      */             }
/*      */           }
/*      */         }
/* 1229 */         if (oldItem == null) {
/* 1230 */           if (mi.getType() == MailItem.Type.DOCUMENT) {
/* 1231 */             newItem = mbox.createDocument(octxt, fldr.getId(), doc.getName(), doc.getContentType(), doc.getCreator(), doc.getDescription(), ais.getInputStream());
/*      */           }
/*      */           else
/*      */           {
/* 1235 */             WikiItem wi = (WikiItem)mi;
/*      */             
/* 1237 */             newItem = mbox.createWiki(octxt, fldr.getId(), wi.getWikiWord(), wi.getCreator(), wi.getDescription(), ais.getInputStream());
/*      */           }
/*      */           
/*      */ 
/* 1241 */           mbox.setDate(octxt, newItem.getId(), doc.getType(), doc.getDate());
/* 1242 */           idMap.put(Integer.valueOf(doc.getId()), Integer.valueOf(newItem.getId()));
/*      */         }
/*      */         
/*      */         break;
/*      */       case FLAG: 
/* 1247 */         return;
/*      */       
/*      */       case FOLDER: 
/* 1250 */         String aclParam = (String)context.params.get("acl");
/* 1251 */         boolean doACL = (aclParam == null) || (!aclParam.equals("0"));
/* 1252 */         Folder f = (Folder)mi;
/* 1253 */         ACL acl = f.getACL();
/* 1254 */         Folder oldF = null;
/* 1255 */         MailItem.Type view = f.getDefaultView();
/* 1256 */         if ((view != MailItem.Type.CONVERSATION) && (view != MailItem.Type.FLAG) && (view != MailItem.Type.TAG))
/*      */         {
/*      */           try
/*      */           {
/* 1260 */             oldF = mbox.getFolderByPath(octxt, path);
/*      */           }
/*      */           catch (Exception e) {}
/* 1263 */           if (oldF != null) {
/* 1264 */             oldItem = oldF;
/* 1265 */             if (r != Resolve.Skip) {
/* 1266 */               if (!f.getUrl().equals(oldF.getUrl())) {
/* 1267 */                 mbox.setFolderUrl(octxt, oldF.getId(), f.getUrl());
/*      */               }
/* 1269 */               if (doACL) {
/* 1270 */                 ACL oldACL = oldF.getACL();
/*      */                 
/* 1272 */                 if (((acl == null) && (oldACL != null)) || ((acl != null) && ((oldACL == null) || (!acl.equals(oldACL)))))
/*      */                 {
/* 1274 */                   mbox.setPermissions(octxt, oldF.getId(), acl);
/*      */                 }
/*      */               }
/*      */             }
/*      */           }
/* 1279 */           if (oldItem == null) {
/* 1280 */             fldr = createParent(context, fmap, path, MailItem.Type.UNKNOWN);
/* 1281 */             Folder.FolderOptions fopt = new Folder.FolderOptions();
/* 1282 */             fopt.setDefaultView(f.getDefaultView()).setFlags(f.getFlagBitmask()).setColor(f.getColor()).setUrl(f.getUrl());
/* 1283 */             newItem = fldr = mbox.createFolder(octxt, f.getName(), fldr.getId(), fopt);
/* 1284 */             if ((doACL) && (acl != null)) {
/* 1285 */               mbox.setPermissions(octxt, fldr.getId(), acl);
/*      */             }
/* 1287 */             fmap.put(Integer.valueOf(fldr.getId()), fldr);
/* 1288 */             fmap.put(fldr.getPath(), fldr); } }
/* 1289 */         break;
/*      */       
/*      */ 
/*      */       case MESSAGE: 
/* 1293 */         Message msg = (Message)mi;
/* 1294 */         Message oldMsg = null;
/*      */         
/* 1296 */         fldr = createPath(context, fmap, path, MailItem.Type.MESSAGE);
/* 1297 */         if ((root) && (r != Resolve.Reset)) {
/*      */           try {
/* 1299 */             oldMsg = mbox.getMessageById(octxt, msg.getId());
/* 1300 */             if ((!msg.getDigest().equals(oldMsg.getDigest())) || (oldMsg.getFolderId() != fldr.getId())) {
/* 1301 */               oldMsg = null;
/*      */             }
/*      */           }
/*      */           catch (Exception e) {}
/*      */         }
/* 1306 */         if (oldMsg == null) {
/* 1307 */           Integer digestId = (Integer)digestMap.get(path);
/*      */           
/* 1309 */           if (digestId == null) {
/* 1310 */             digestMap.clear();
/* 1311 */             digestMap.put(path, Integer.valueOf(-1));
/*      */             try {
/* 1313 */               for (MailItem item : mbox.getItemList(octxt, MailItem.Type.MESSAGE, fldr.getId())) {
/* 1314 */                 digestMap.put(item.getDigest(), Integer.valueOf(item.getId()));
/*      */               }
/*      */             }
/*      */             catch (Exception e) {}
/*      */           }
/* 1319 */           digestId = (Integer)digestMap.get(mi.getDigest());
/* 1320 */           if (digestId != null) {
/* 1321 */             oldMsg = mbox.getMessageById(octxt, digestId.intValue());
/* 1322 */             if (!msg.getDigest().equals(oldMsg.getDigest())) {
/* 1323 */               oldMsg = null;
/*      */             }
/*      */           }
/*      */         }
/* 1327 */         if (oldMsg != null) {
/* 1328 */           if (r == Resolve.Replace) {
/* 1329 */             mbox.delete(octxt, oldMsg.getId(), oldMsg.getType());
/*      */           } else {
/* 1331 */             oldItem = oldMsg;
/*      */           }
/*      */         }
/* 1334 */         if (oldItem == null) {
/* 1335 */           DeliveryOptions opt = new DeliveryOptions().setFolderId(fldr.getId()).setNoICal(true).setFlags(msg.getFlagBitmask()).setTags(msg.getTags());
/*      */           
/*      */ 
/*      */ 
/* 1339 */           newItem = mbox.addMessage(octxt, ais.getInputStream(), (int)aie.getSize(), Long.valueOf(msg.getDate()), opt, null, id); }
/* 1340 */         break;
/*      */       
/*      */ 
/*      */       case MOUNTPOINT: 
/* 1344 */         Mountpoint mp = (Mountpoint)mi;
/* 1345 */         MailItem oldMP = null;
/*      */         try
/*      */         {
/* 1348 */           oldMP = mbox.getItemByPath(octxt, path);
/* 1349 */           if (oldMP.getType() == mi.getType()) {
/* 1350 */             oldMP = null;
/*      */           }
/*      */         }
/*      */         catch (Exception e) {}
/* 1354 */         if (oldMP != null) {
/* 1355 */           if ((r == Resolve.Modify) || (r == Resolve.Replace)) {
/* 1356 */             mbox.delete(octxt, oldMP.getId(), oldMP.getType());
/*      */           } else {
/* 1358 */             oldItem = oldMP;
/*      */           }
/*      */         }
/* 1361 */         if (oldItem == null) {
/* 1362 */           fldr = createParent(context, fmap, path, MailItem.Type.UNKNOWN);
/* 1363 */           newItem = mbox.createMountpoint(context.opContext, fldr.getId(), mp.getName(), mp.getOwnerId(), mp.getRemoteId(), mp.getRemoteUuid(), mp.getDefaultView(), mp.getFlagBitmask(), mp.getColor(), mp.isReminderEnabled());
/*      */         }
/*      */         
/*      */ 
/*      */ 
/*      */ 
/*      */         break;
/*      */       case NOTE: 
/* 1371 */         Note note = (Note)mi;
/* 1372 */         Note oldNote = null;
/*      */         
/* 1374 */         fldr = createPath(context, fmap, path, MailItem.Type.NOTE);
/*      */         try {
/* 1376 */           for (Note listNote : mbox.getNoteList(octxt, fldr.getId())) {
/* 1377 */             if (note.getSubject().equals(listNote.getSubject())) {
/* 1378 */               oldNote = listNote;
/* 1379 */               break;
/*      */             }
/*      */           }
/*      */         }
/*      */         catch (Exception e) {}
/* 1384 */         if (oldNote != null) {
/* 1385 */           if (r == Resolve.Replace) {
/* 1386 */             mbox.delete(octxt, oldNote.getId(), oldNote.getType());
/*      */           } else {
/* 1388 */             oldItem = oldNote;
/* 1389 */             if (r == Resolve.Modify) {
/* 1390 */               mbox.editNote(octxt, oldItem.getId(), new String(readArchiveEntry(ais, aie), UTF8));
/*      */             }
/*      */             
/*      */           }
/*      */         }
/* 1395 */         else if (oldItem == null) {
/* 1396 */           newItem = mbox.createNote(octxt, new String(readArchiveEntry(ais, aie), UTF8), note.getBounds(), note.getColor(), fldr.getId());
/*      */         }
/*      */         
/*      */         break;
/*      */       case SEARCHFOLDER: 
/* 1401 */         SearchFolder sf = (SearchFolder)mi;
/* 1402 */         MailItem oldSF = null;
/*      */         try
/*      */         {
/* 1405 */           oldSF = mbox.getItemByPath(octxt, path);
/* 1406 */           if (oldSF.getType() == mi.getType()) {
/* 1407 */             oldSF = null;
/*      */           }
/*      */         }
/*      */         catch (Exception e) {}
/* 1411 */         if (oldSF != null) {
/* 1412 */           if (r == Resolve.Modify) {
/* 1413 */             mbox.modifySearchFolder(octxt, oldSF.getId(), sf.getQuery(), sf.getReturnTypes(), sf.getSortField());
/*      */ 
/*      */           }
/* 1416 */           else if (r == Resolve.Replace) {
/* 1417 */             mbox.delete(octxt, oldSF.getId(), oldSF.getType());
/*      */           } else {
/* 1419 */             oldItem = oldSF;
/*      */           }
/*      */         }
/* 1422 */         if (oldItem == null) {
/* 1423 */           fldr = createParent(context, fmap, path, MailItem.Type.UNKNOWN);
/* 1424 */           newItem = mbox.createSearchFolder(octxt, fldr.getId(), sf.getName(), sf.getQuery(), sf.getReturnTypes(), sf.getSortField(), sf.getFlagBitmask(), sf.getColor());
/*      */         }
/*      */         
/*      */ 
/*      */         break;
/*      */       case TAG: 
/* 1430 */         Tag tag = (Tag)mi;
/*      */         try
/*      */         {
/* 1433 */           Tag oldTag = mbox.getTagByName(octxt, tag.getName());
/* 1434 */           oldItem = oldTag;
/*      */         }
/*      */         catch (Exception e) {}
/* 1437 */         if (oldItem == null) {
/* 1438 */           newItem = mbox.createTag(octxt, tag.getName(), tag.getColor());
/*      */         }
/*      */         
/*      */         break;
/*      */       case VIRTUAL_CONVERSATION: 
/* 1443 */         return;
/*      */       }
/*      */       
/* 1446 */       if (newItem != null) {
/* 1447 */         if (mi.getColor() != newItem.getColor()) {
/* 1448 */           mbox.setColor(octxt, newItem.getId(), newItem.getType(), mi.getColor());
/*      */         }
/* 1450 */         if ((!id.flags.equals(newItem.getFlagString())) || (!id.tagsEqual(newItem))) {
/* 1451 */           mbox.setTags(octxt, newItem.getId(), newItem.getType(), Flag.toBitmask(id.flags), getTagNames(id), null);
/*      */         }
/*      */       }
/* 1454 */       else if ((oldItem != null) && (r == Resolve.Modify)) {
/* 1455 */         if (mi.getColor() != oldItem.getColor()) {
/* 1456 */           mbox.setColor(octxt, oldItem.getId(), oldItem.getType(), mi.getColor());
/*      */         }
/* 1458 */         if ((!id.flags.equals(oldItem.getFlagString())) || (!id.tagsEqual(oldItem))) {
/* 1459 */           mbox.setTags(octxt, oldItem.getId(), oldItem.getType(), Flag.toBitmask(id.flags), getTagNames(id), null);
/*      */         }
/*      */       }
/*      */     }
/*      */     catch (MailServiceException e) {
/* 1464 */       if (e.getCode() == "mail.QUOTA_EXCEEDED")
/* 1465 */         throw e;
/* 1466 */       if ((r != Resolve.Skip) || (e.getCode() != "mail.ALREADY_EXISTS"))
/*      */       {
/* 1468 */         addError(errs, e);
/*      */       }
/*      */     } catch (Exception e) {
/* 1471 */       addError(errs, FormatterServiceException.UNKNOWN_ERROR(id.path, e));
/*      */     }
/*      */   }
/*      */   
/*      */   private void addData(UserServletContext context, Folder fldr, Map<Object, Folder> fmap, Set<MailItem.Type> types, Resolve r, boolean timestamp, ArchiveInputStream ais, ArchiveInputEntry aie, List<ServiceException> errs)
/*      */     throws ServiceException
/*      */   {
/*      */     try
/*      */     {
/* 1480 */       Mailbox mbox = fldr.getMailbox();
/*      */       
/* 1482 */       String name = aie.getName();
/* 1483 */       int idx = name.lastIndexOf('/');
/* 1484 */       MailItem newItem = null;
/* 1485 */       OperationContext oc = context.opContext;
/*      */       String dir;
/*      */       String file;
/*      */       String dir;
/* 1489 */       if (idx == -1) {
/* 1490 */         String file = name;
/* 1491 */         dir = "";
/*      */       } else {
/* 1493 */         file = name.substring(idx + 1);
/* 1494 */         dir = name.substring(0, idx + 1);
/* 1495 */         if (!dir.startsWith("/"))
/* 1496 */           dir = '/' + dir;
/*      */       }
/* 1498 */       if (file.length() == 0) return;
/*      */       MailItem.Type view;
/* 1500 */       int defaultFldr; MailItem.Type type; MailItem.Type view; if ((file.endsWith(".csv")) || (file.endsWith(".vcf"))) {
/* 1501 */         int defaultFldr = 7;
/* 1502 */         MailItem.Type type = MailItem.Type.CONTACT;
/* 1503 */         view = MailItem.Type.CONTACT; } else { MailItem.Type view;
/* 1504 */         if (file.endsWith(".eml")) {
/* 1505 */           int defaultFldr = 2;
/* 1506 */           MailItem.Type type = MailItem.Type.MESSAGE;
/* 1507 */           view = MailItem.Type.MESSAGE; } else { MailItem.Type view;
/* 1508 */           if (file.endsWith(".ics")) { MailItem.Type view;
/* 1509 */             if (dir.startsWith("Tasks/")) {
/* 1510 */               int defaultFldr = 15;
/* 1511 */               MailItem.Type type = MailItem.Type.TASK;
/* 1512 */               view = MailItem.Type.TASK;
/*      */             } else {
/* 1514 */               int defaultFldr = 10;
/* 1515 */               MailItem.Type type = MailItem.Type.APPOINTMENT;
/* 1516 */               view = MailItem.Type.APPOINTMENT;
/*      */             } } else { MailItem.Type view;
/* 1518 */             if (file.endsWith(".wiki")) {
/* 1519 */               int defaultFldr = 12;
/* 1520 */               MailItem.Type type = MailItem.Type.WIKI;
/* 1521 */               view = MailItem.Type.WIKI;
/*      */             } else {
/* 1523 */               defaultFldr = 16;
/* 1524 */               type = MailItem.Type.DOCUMENT;
/* 1525 */               view = MailItem.Type.DOCUMENT;
/*      */             } } } }
/* 1527 */       if ((types != null) && (!types.contains(type))) {
/* 1528 */         return;
/*      */       }
/* 1530 */       if (dir.equals("")) {
/* 1531 */         if (fldr.getPath().equals("/")) {
/* 1532 */           fldr = mbox.getFolderById(oc, defaultFldr);
/*      */         }
/* 1534 */         if ((fldr.getDefaultView() != MailItem.Type.UNKNOWN) && (fldr.getDefaultView() != view) && (((view != MailItem.Type.DOCUMENT) && (view != MailItem.Type.WIKI)) || ((fldr.getDefaultView() != MailItem.Type.DOCUMENT) && (fldr.getDefaultView() != MailItem.Type.WIKI))))
/*      */         {
/*      */ 
/*      */ 
/* 1538 */           throw FormatterServiceException.INVALID_TYPE(view.toString(), fldr.getPath());
/*      */         }
/*      */       } else {
/* 1541 */         String s = fldr.getPath();
/*      */         
/* 1543 */         if (!s.endsWith("/"))
/* 1544 */           s = s + '/';
/* 1545 */         if (dir.startsWith(s))
/* 1546 */           dir = dir.substring(s.length());
/* 1547 */         fldr = createPath(context, fmap, fldr.getPath() + dir, view);
/*      */       }
/* 1549 */       switch (type) {
/*      */       case APPOINTMENT: 
/*      */       case TASK: 
/* 1552 */         boolean continueOnError = context.ignoreAndContinueOnError();
/* 1553 */         boolean preserveExistingAlarms = context.preserveAlarms();
/* 1554 */         InputStream is = ais.getInputStream();
/*      */         try
/*      */         {
/* 1557 */           if (aie.getSize() <= LC.calendar_ics_import_full_parse_max_size.intValue())
/*      */           {
/* 1559 */             List<ZCalendar.ZVCalendar> icals = ZCalendar.ZCalendarBuilder.buildMulti(is, UTF8);
/* 1560 */             IcsImportParseHandler.ImportInviteVisitor visitor = new IcsImportParseHandler.ImportInviteVisitor(oc, fldr, preserveExistingAlarms);
/*      */             
/*      */ 
/* 1563 */             Invite.createFromCalendar(context.targetAccount, null, icals, true, continueOnError, visitor);
/*      */           }
/*      */           else {
/* 1566 */             ZCalendar.ZICalendarParseHandler handler = new IcsImportParseHandler(oc, context.targetAccount, fldr, continueOnError, preserveExistingAlarms);
/*      */             
/*      */ 
/* 1569 */             ZCalendar.ZCalendarBuilder.parse(is, UTF8, handler);
/*      */           }
/*      */         } finally {
/* 1572 */           is.close();
/*      */         }
/* 1574 */         break;
/*      */       case CONTACT: 
/* 1576 */         if (file.endsWith(".csv")) {
/* 1577 */           BufferedReader reader = new BufferedReader(new InputStreamReader(ais.getInputStream(), UTF8));
/*      */           
/* 1579 */           ImportContacts.ImportCsvContacts(oc, context.targetMailbox, new ItemId(fldr), ContactCSV.getContacts(reader, null));
/*      */         }
/*      */         else {
/* 1582 */           List<VCard> cards = VCard.parseVCard(new String(readArchiveEntry(ais, aie), UTF8));
/*      */           
/*      */ 
/* 1585 */           if ((cards == null) || (cards.size() == 0) || ((cards.size() == 1) && (((VCard)cards.get(0)).fields.isEmpty())))
/*      */           {
/* 1587 */             addError(errs, FormatterServiceException.MISSING_VCARD_FIELDS(name));
/*      */             
/* 1589 */             return;
/*      */           }
/* 1591 */           for (VCard vcf : cards) {
/* 1592 */             if (!vcf.fields.isEmpty())
/*      */             {
/* 1594 */               mbox.createContact(oc, vcf.asParsedContact(), fldr.getId(), null);
/*      */             }
/*      */           }
/*      */         }
/* 1598 */         break;
/*      */       case WIKI: 
/*      */       case DOCUMENT: 
/* 1601 */         String creator = context.getAuthAccount() == null ? null : context.getAuthAccount().getName();
/*      */         try
/*      */         {
/* 1604 */           MailItem oldItem = mbox.getItemByPath(oc, file, fldr.getId());
/* 1605 */           if (oldItem.getType() != type) {
/* 1606 */             addError(errs, FormatterServiceException.MISMATCHED_TYPE(name));
/* 1607 */           } else { if (r == Resolve.Replace) {
/* 1608 */               mbox.delete(oc, oldItem.getId(), type);
/* 1609 */               throw MailServiceException.NO_SUCH_ITEM(oldItem.getId()); }
/* 1610 */             if (r != Resolve.Skip) {
/* 1611 */               newItem = mbox.addDocumentRevision(oc, oldItem.getId(), creator, oldItem.getName(), null, ais.getInputStream());
/*      */             }
/*      */           }
/*      */         } catch (MailServiceException.NoSuchItemException e) {
/* 1615 */           if (type == MailItem.Type.WIKI) {
/* 1616 */             newItem = mbox.createWiki(oc, fldr.getId(), file, creator, null, ais.getInputStream());
/*      */           } else {
/* 1618 */             newItem = mbox.createDocument(oc, fldr.getId(), file, null, creator, null, ais.getInputStream());
/*      */           }
/*      */         }
/* 1621 */         if ((newItem != null) && 
/* 1622 */           (timestamp)) {
/* 1623 */           mbox.setDate(oc, newItem.getId(), type, aie.getModTime());
/*      */         }
/*      */         break;
/*      */       case MESSAGE: 
/* 1627 */         int flags = aie.isUnread() ? Flag.BITMASK_UNREAD : 0;
/* 1628 */         DeliveryOptions opt = new DeliveryOptions().setFolderId(fldr.getId()).setNoICal(true).setFlags(flags);
/*      */         
/*      */ 
/* 1631 */         mbox.addMessage(oc, ais.getInputStream(), (int)aie.getSize(), Long.valueOf(timestamp ? aie.getModTime() : -2L), opt, null);
/*      */       }
/*      */     }
/*      */     catch (Exception e)
/*      */     {
/* 1636 */       if (((e instanceof MailServiceException)) && (((MailServiceException)e).getCode() == "mail.QUOTA_EXCEEDED"))
/*      */       {
/* 1638 */         throw ((MailServiceException)e);
/*      */       }
/* 1640 */       addError(errs, FormatterServiceException.UNKNOWN_ERROR(aie.getName(), e));
/*      */     }
/*      */   }
/*      */   
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */ 
/*      */   private String sanitize(String str, CharsetEncoder encoder)
/*      */   {
/* 1653 */     if (encoder.canEncode(str)) {
/* 1654 */       return str;
/*      */     }
/* 1656 */     StringBuilder buf = new StringBuilder(str.length());
/* 1657 */     for (int i = 0; i < str.length(); i++) {
/* 1658 */       char c = str.charAt(i);
/* 1659 */       if (encoder.canEncode(c)) {
/* 1660 */         buf.append(c);
/*      */       } else {
/* 1662 */         buf.append('#');
/*      */       }
/*      */     }
/* 1665 */     return buf.toString();
/*      */   }
/*      */   
/*      */   public static abstract interface ArchiveInputEntry
/*      */   {
/*      */     public abstract long getModTime();
/*      */     
/*      */     public abstract String getName();
/*      */     
/*      */     public abstract long getSize();
/*      */     
/*      */     public abstract int getType();
/*      */     
/*      */     public abstract boolean isUnread();
/*      */   }
/*      */   
/*      */   public static abstract interface ArchiveOutputEntry
/*      */   {
/*      */     public abstract void setUnread();
/*      */     
/*      */     public abstract void setSize(long paramLong);
/*      */   }
/*      */   
/*      */   public static abstract interface ArchiveInputStream
/*      */     extends Closeable
/*      */   {
/*      */     public abstract InputStream getInputStream();
/*      */     
/*      */     public abstract ArchiveFormatter.ArchiveInputEntry getNextEntry()
/*      */       throws IOException;
/*      */     
/*      */     public abstract int read(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
/*      */       throws IOException;
/*      */   }
/*      */   
/*      */   public static abstract interface ArchiveOutputStream
/*      */     extends Closeable
/*      */   {
/*      */     public abstract void closeEntry()
/*      */       throws IOException;
/*      */     
/*      */     public abstract OutputStream getOutputStream();
/*      */     
/*      */     public abstract int getRecordSize();
/*      */     
/*      */     public abstract ArchiveFormatter.ArchiveOutputEntry newOutputEntry(String paramString1, String paramString2, int paramInt, long paramLong);
/*      */     
/*      */     public abstract void putNextEntry(ArchiveFormatter.ArchiveOutputEntry paramArchiveOutputEntry)
/*      */       throws IOException;
/*      */     
/*      */     public abstract void write(byte[] paramArrayOfByte)
/*      */       throws IOException;
/*      */     
/*      */     public abstract void write(byte[] paramArrayOfByte, int paramInt1, int paramInt2)
/*      */       throws IOException;
/*      */   }
/*      */ }


/* Location:              /home/mint/zimbrastore.jar!/com/zimbra/cs/service/formatter/ArchiveFormatter.class
 * Java compiler version: 7 (51.0)
 * JD-Core Version:       0.7.1
 */